﻿/********************************************************************************
** @ Date:2025/04/07
** @ Author: Gaojia
** @ Description: 测点、设备和节点的基类，统一接口管理节点生命周期、状态及基本信息
** @ Version:1.0.0
** @ Fun: 提供统一启动、停止、更新数据接口；封装 ID 和名称；支持数据更新信号
********************************************************************************/
#ifndef C_BASENODE_H
#define C_BASENODE_H
#include <QObject>
#include <QString>
#include <QTreeView>
#include <QStandardItemModel>
#include <QStandardItem>
// 节点状态枚举
enum class ENodeStatus {
	enIdle,     // 空闲状态，尚未启动或初始化完成
	enRun,      // 正常运行中
	enFault,    // 故障状态，设备或节点异常
	enDispose   // 即将被销毁
};

// 基类：所有测点、设备或子系统节点的公共基类
class CBaseNode : public QObject
{
	Q_OBJECT
public:
	enum ENodeType {
		enRoot,
		enNode,
		enDevice,
		enMeasurePoint
	};
	// 构造函数
	// @param sId 节点唯一标识符
	// @param sName 节点名称
	// @param parent 父对象
	CBaseNode(const QString& sId, const QString& sName, const QString& sConfig = "", QObject* parent = nullptr)
		: QObject(parent), m_sId(sId), m_sName(sName), m_sConfig(sConfig), m_eNodeStatus(ENodeStatus::enIdle)
	{
		m_sTechAlarmArea = "A001";
		m_sFaultAlarmArea = "A101";
		m_pParent = NULL;
		this->setParent(parent);
		m_pItem = new QStandardItem(sName);
		m_pItem->setData(QVariant::fromValue(reinterpret_cast<void*>(this)), Qt::UserRole);
		m_eNodeType = enRoot;
		m_sConfig = sConfig;
		m_pItem->setIcon(QIcon(":/SmartControl/Resource/toolbar/root.png"));
	}

	virtual ~CBaseNode()
	{
		//delete m_pItem;
		for (auto child : m_pVecChildren) { delete child; }
	}
	// 获取节点类型
	ENodeType getType() const { return m_eNodeType; }
	// 获取节点ID
	QString getId() const { return m_sId; }
	// 获取节点ID
	QString getConfig() const { return m_sConfig; }
	// 获取节点名称
	QString getName() const { return m_sName; }
	// 获取节点状态
	ENodeStatus getNodeStatus() const { return m_eNodeStatus; }
	// 获取工艺报警区
	QString getTechAlarmArea() const { return m_sTechAlarmArea; }
	// 获取故障报警区
	QString getFaultAlarmArea() const { return m_sFaultAlarmArea; }
	// 获取父节点
	CBaseNode* getParent() const { return m_pParent; }
	// 获取子节点
	QVector<CBaseNode*>& getChildren() { return m_pVecChildren; }
	//获取Ui节点
	QStandardItem * getItem() const { return m_pItem; }
	//获取当前测点地址
	QString getCompletepath()
	{
		QString sReAddr = m_sId;
		CBaseNode *pNode = getParent();
		while (pNode != nullptr)
		{
			sReAddr = pNode->getId()+"."+ sReAddr;
			pNode = pNode->getParent();
		}
		return sReAddr;
	}
	//获取当前测点地址名称
	QString getCompletepathName()
	{
		QString sReAddr = m_sName;
		CBaseNode* pNode = getParent();
		while (pNode != nullptr)
		{
			sReAddr = pNode->getName() + "/" + sReAddr;
			pNode = pNode->getParent();
		}
		return sReAddr;
	}
	void setName(QString sName) { m_sName = sName; }

	// 设置节点状态
	void  setNodeStatus(ENodeStatus enStatus)  { m_eNodeStatus=enStatus; }
	// 设置工艺报警区
	void setTechAlarmArea(QString sStr) { m_sTechAlarmArea = sStr; }
	// 设置故障报警区
	void setFaultAlarmArea(QString sStr)  { m_sFaultAlarmArea = sStr; }

	void showItem(QTreeView *pTree)
	{
		QModelIndex index = m_pItem->index(); // 获取该 item 对应的 QModelIndex
		pTree->expand(index);            // 展开这个节点
		pTree->setCurrentIndex(index);   // 可选：高亮选中
	}

	void setItemName(QString sName) { m_pItem->setText(m_sName); }
	// 添加、删除和清空子节点
	void addChild(CBaseNode* child)
	{
		if (!child) return;
		child->m_pParent = this;
		m_pVecChildren.append(child);
		if (child->getType() == enRoot || child->getType() == enNode)
		{
			m_pItem->appendRow(child->getItem());
		}	
	}
	void addChild(int nIndex, CBaseNode* child)
	{
		if (!child || child == this) return;
		// 如果该子节点已经有父节点，先从原父节点中移除
		if (child->getParent() && child->getParent() != this)
		{
			child->getParent()->removeChild(child);
		}
		// 修正插入位置
		if (nIndex < 0 || nIndex > m_pVecChildren.size())
		{
			nIndex = m_pVecChildren.size();
		}
		// 插入子节点
		m_pVecChildren.insert(nIndex, child);
		m_pItem->insertRow(nIndex, child->getItem());
		// 设置其父节点为当前节点
		child->m_pParent = this;
	}
	virtual void removeChild(CBaseNode* child)
	{
		if (!child) return;
		m_pVecChildren.removeOne(child);         // 从子节点列表中移除
		QList<QStandardItem*> taken = m_pItem->takeRow(child->getItem()->row());
	}
	//删除当前节点和子节点
	virtual void deleteNode()
	{
		m_pParent->removeChild(this);
		for (int i = m_pVecChildren.size() - 1; i >= 0; i--)
		{
			m_pItem->takeRow(m_pVecChildren[i]->getItem()->row());
			m_pVecChildren[i]->deleteNode();
		}
		delete this;
	}
	void deleteChild(CBaseNode* child)
	{
		if (!child) return;
		m_pVecChildren.removeOne(child);             // 从子节点列表中移除
		m_pItem->removeRow(child->getItem()->row()); // 从 QStandardItemModel 中移除子节点
		delete child;                                // 删除子节点对象
	}
	void clearChildren()
	{
		for (CBaseNode* child : m_pVecChildren) {
			m_pItem->removeRow(child->getItem()->row());  // 从 QStandardItemModel 中移除
			delete child;   // 删除子节点对象
		}
		m_pVecChildren.clear();  // 清空子节点列表
	}
	CBaseNode* cloneRecursive() 
	{
		// 创建一个新节点对象，使用当前对象的数据构造
		CBaseNode* cloned = new CBaseNode(m_sId, m_sName);

		// 拷贝类型与状态
		cloned->m_eNodeType = this->m_eNodeType;
		cloned->m_eNodeStatus = this->m_eNodeStatus;

		// 克隆 QStandardItem（只克隆文本即可）
		cloned->m_pItem = new QStandardItem(m_sName);
		cloned->m_pItem->setData(QVariant::fromValue(reinterpret_cast<void*>(cloned)), Qt::UserRole);

		// 递归克隆所有子节点
		for (CBaseNode* child : m_pVecChildren) {
			CBaseNode* clonedChild = child->cloneRecursive();
			cloned->addChild(clonedChild);  // 自动加入子节点树结构
		}

		return cloned;
	}
	// 递归查找：根据 ID 返回子节点（包括所有孙节点）
	CBaseNode* findNodeById(const QString& sId)
	{
		if (sId == "")return nullptr;
		if (this->m_sId == sId) return this;

		for (CBaseNode* pChild : m_pVecChildren) {
			CBaseNode* pFound = pChild->findNodeById(sId); // 递归查找子节点
			if (pFound != nullptr)
				return pFound;
		}

		return nullptr; // 未找到
	}

	/**
	* @ Author: Gaojia
	* @ Description: 寻找根节点
	*/
	CBaseNode* findRootNode()
	{
		if (m_pParent != NULL)
		{
			return m_pParent->findRootNode();
		}
		else
		{
			return this;
		}
	}

	CBaseNode* findNodeByAddr(const QString& sId)
	{
		QStringList sList = sId.split(".");
		CBaseNode *pNode = findRootNode();
		for (int i = 1; i < sList.size(); i++)
		{
			bool bFind = false;
			for (int j = 0; j < pNode->getChildren().size(); j++)
			{
				if (sList[i] == pNode->getChildren()[j]->getId())
				{
					pNode = pNode->getChildren()[j];
					bFind = true;
					break;
				}
			}
			if (!bFind)
			{
				return nullptr;
			}
		}
		return pNode;
	}

	//释放节点、设备或者测点
	virtual void disposeNode(CBaseNode* pNode)
	{

	}
	// 启动节点（由子类实现具体逻辑）
	virtual void start() 
	{
		for (int i = 0; i < m_pVecChildren.size(); i++)
		{
			m_pVecChildren[i]->start();
		}
	};
	// 停止节点（由子类实现具体逻辑）
	virtual void stop() 
	{
		for (int i = 0; i < m_pVecChildren.size(); i++)
		{
			m_pVecChildren[i]->stop();
		}
	};
	// 更新节点数据（由子类实现具体逻辑）
	virtual void updateData() {};

	//所有节点初始化 备注 现阶段只初始化设备的 节点后二次测点后面根据需要添加
	virtual void init()
	{
		for (CBaseNode* pChild : m_pVecChildren) 
		{
			pChild->init();
		}
	};
signals:
	// 数据更新信号（可用于界面刷新、上报等）
	void dataUpdated();

protected:
	QString m_sId;                      // 节点唯一标识符
	QString m_sName;                    // 节点名称
	QString m_sConfig;                  // 设备私有配置信息
	ENodeStatus m_eNodeStatus;          // 节点当前状态
	ENodeType m_eNodeType;              // 节点类型
	CBaseNode* m_pParent;               // 父节点   
	QVector<CBaseNode*> m_pVecChildren; // 子节点
	QMap<QString,CBaseNode*> m_mapVecChildren; // 子节点
	QStandardItem* m_pItem;             // 当前树节点对象  
	QStandardItem* m_pItemEdit;         // 编辑树节点对象  
	QString m_sTechAlarmArea;           //工艺报警区
	QString m_sFaultAlarmArea;           //故障报警区
	//bool m_b
};

#endif // C_BASENODE_H
